package com.negative.logic;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Environment;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class BarcodeGenerator {

	/**
	 * 
	 * @param barcodeDate The string the QR will represent
	 * @return A bitmap contains the QR or null in case of a failure.
	 */
	public static Bitmap createQRBarcode(String barcodeData)
	{
		if(barcodeData == null)
		{
			return null;
		}
		String qrCodeData = barcodeData;
		String charset = "UTF-8"; // or "ISO-8859-1"
		Map<EncodeHintType, ErrorCorrectionLevel> hintMap = new HashMap<EncodeHintType, ErrorCorrectionLevel>();
		hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
		try {
			return createQRCode(qrCodeData, charset, hintMap, 400, 400);
		} catch (WriterException e) {
			// TODO Auto-generated catch block
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			return null;
		}
	}

	private static Bitmap createQRCode(String qrCodeData,
			String charset, Map hintMap, int qrCodeheight, int qrCodewidth)
					throws WriterException, IOException {
		BitMatrix matrix = new MultiFormatWriter().encode(
				new String(qrCodeData.getBytes(charset), charset),
				BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
		
		return toBitmap(matrix);		
	}
	
	private boolean saveBitmapOnStorage(Bitmap barcode, String fileName)
	{
		File sdcard = Environment.getExternalStorageDirectory();
		FileOutputStream out = null;
		try {
		    out = new FileOutputStream(new File(sdcard, fileName));
		    boolean success = barcode.compress(Bitmap.CompressFormat.JPEG, 100, out);
		    return success;
		} catch (FileNotFoundException e) {
		    e.printStackTrace();
		} finally {
		    if (out != null) try {
		        out.close();
		    } catch (IOException e) {
		        e.printStackTrace();
		    }
		}
		return false;
	}
	
	private static Bitmap toBitmap(BitMatrix matrix){
	    int height = matrix.getHeight();
	    int width = matrix.getWidth();
	    Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
	    for (int x = 0; x < width; x++){
	        for (int y = 0; y < height; y++){
	            bmp.setPixel(x, y, matrix.get(x,y) ? Color.BLACK : Color.WHITE);
	        }
	    }
	    return bmp;
	}
	
	public static String readQRCode(Bitmap bitmap)
			throws FileNotFoundException, IOException, NotFoundException {
	
		int width = bitmap.getWidth(), height = bitmap.getHeight();
        int[] pixels = new int[width * height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        bitmap.recycle();
        bitmap = null;
        RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
        
		
		Result qrCodeResult = new MultiFormatReader().decode(binaryBitmap);
		return qrCodeResult.getText();
	}
}
